﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Runtime.Serialization;
using System.Windows.Forms;
using PMC.Interfaces;
using PMC.Structs;

namespace PMC
{
    [DataContract]
    public class UrlExpressions : IEnumerable<Expressions>, ISaveloadable
    {
        private static UrlExpressions _instance;
        public static UrlExpressions Instance
        {
            get { return _instance ?? (_instance = new UrlExpressions()); }
        }

        [DataMember(Name = "Expressions")]
        private List<Expressions> _expressions;

        public IList<Expressions> Expressions {
            get { return _expressions; }
        }

        private readonly string _path = Properties.Settings.Default.SettingsFolder + Properties.Settings.Default.ExpressionsFile;

        private UrlExpressions()
        {
            Load();
        }

        /// <summary>
        /// Add expression to the list
        /// </summary>
        /// <param name="e">Expression to add</param>
        /// <exception cref="DuplicateNameException">Expression already exist</exception>
        public void Add(Expressions e)
        {
            var exp = _expressions.Find(c => c.Expression == e.Expression);
            if (exp != default(Expressions))
                throw new DuplicateNameException<Expressions>("Expression already exists", null, exp);
                //if (over.AllowOverride(e.Expression) == DialogResult.OK)
                //    _expressions.Remove(exp);
                //else
                //    return;
            _expressions.Add(e);
            Changed = true;
        }

        //public void Remove(int removeAt)
        //{
        //    _expressions.RemoveAt(removeAt);
        //}

        /// <summary>
        /// Removes <b>Expressions</b> from expression-list
        /// </summary>
        /// <param name="expressions">Expression to remove</param>
        public void Remove(Expressions expressions)
        {
            _expressions.Remove(expressions);
            Changed = true;
        }

        //public void Load(List<string> expressions, List<string> exceptions)
        //{
        //    foreach (var exception in exceptions)
        //    {
        //        AddException(exception);
        //    }
        //    foreach (var expression in expressions)
        //    {
        //        AddExpression(expression);
        //    }
        //}

        public bool Changed { get; private set; }

        public void Load()
        {
            _expressions = Global.XMLDeserialize<List<Expressions>>(_path) ?? new List<Expressions>();
            Changed = false;
        }

        //Save
        public void Save()
        {
            Global.XMLSerialize(_path, _expressions);
            Changed = false;
        }

        public void Reload()
        {
            Load();
        }

        /// <summary>
        /// Test string to the expressions
        /// </summary>
        /// <param name="str">String to test</param>
        /// <returns><b>True</b> if string matches, <b>False</b> when not</returns>
        public bool TestString(string str)
        {
            bool hasExpression = false;
            foreach (var expression in _expressions)
            {
                if (!str.Contains(expression))
                    continue;

                if (expression.Type == ExpressionTypes.Expression)
                    hasExpression = true;
                else
                    return false; //If a string matches an exception it will automaticly return false!
            }
            return hasExpression;
        }

        #region Implementation of IEnumerable

        public IEnumerator<Expressions> GetEnumerator()
        {
            return _expressions.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion
    }
}
